package com.ckjava.test.gencode.component;

import com.ckjava.test.component.TemplateCom;
import com.ckjava.test.gencode.entity.GenScheme;
import com.ckjava.test.gencode.entity.GenTable;
import com.ckjava.test.gencode.entity.GenTableColumn;
import com.ckjava.test.gencode.entity.GenTemplate;
import com.ckjava.test.gencode.service.GenCodeService;
import com.ckjava.test.utils.JaxbMapper;
import com.ckjava.test.utils.StringUtils;
import com.ckjava.xutils.Constants;
import com.ckjava.xutils.DateUtils;
import com.ckjava.xutils.FileUtils;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.Date;
import java.util.Map;

@Component
public class GenCom {

    private String path = "D:/git-workspace/play/SpringBoot/spring-boot-mybatis";
    private String dbType = "mysql";

    private static Logger logger = LoggerFactory.getLogger(GenCom.class);

    @Autowired
    private TemplateCom templateCom;
    @Autowired
    private GenCodeService genCodeService;

    /**
     * XML文件转换为对象
     * @param fileName
     * @param clazz
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T fileToObject(String fileName, Class<?> clazz){
        try {
            String pathName = "/gen/" + fileName;
            Resource resource = new ClassPathResource(pathName);
            InputStream is = resource.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            StringBuilder sb = new StringBuilder();
            while (true) {
                String line = br.readLine();
                if (line == null){
                    break;
                }
                sb.append(line).append("\r\n");
            }
            if (is != null) {
                is.close();
            }
            if (br != null) {
                br.close();
            }
            return (T) JaxbMapper.fromXml(sb.toString(), clazz);
        } catch (IOException e) {
            logger.warn("Error file convert: {}", e.getMessage());
        }
        return null;
    }

    public static Map<String, Object> getDataModel(GenScheme genScheme){
        Map<String, Object> model = Maps.newHashMap();

        model.put("packageName", com.ckjava.xutils.StringUtils.lowerCase(genScheme.getPackageName()));
        model.put("lastPackageName", com.ckjava.xutils.StringUtils.substringAfterLast((String)model.get("packageName"),"."));
        model.put("moduleName", com.ckjava.xutils.StringUtils.lowerCase(genScheme.getModuleName()));
        model.put("subModuleName", com.ckjava.xutils.StringUtils.lowerCase(genScheme.getSubModuleName()));
        model.put("className", com.ckjava.xutils.StringUtils.uncapitalize(genScheme.getGenTable().getClassName()));
        model.put("ClassName", com.ckjava.xutils.StringUtils.capitalize(genScheme.getGenTable().getClassName()));

        model.put("functionName", genScheme.getFunctionName());
        model.put("functionNameSimple", genScheme.getFunctionNameSimple());
        model.put("functionAuthor", genScheme.getFunctionAuthor());
        model.put("functionVersion", DateUtils.formatTime(new Date().getTime(), DateUtils.TIMEFORMAT.DATE));

        model.put("table", genScheme.getGenTable());

        return model;
    }

    /**
     * 初始化列属性字段
     *
     * @param genTable
     */
    public static void initColumnField(GenTable genTable) {
        for (GenTableColumn column : genTable.getColumnList()) {

            // 如果是不是新增列，则跳过。
            /*if (column.getId() == null) {
                continue;
            }*/

            // 设置字段说明
            if (StringUtils.isBlank(column.getComments())) {
                column.setComments(column.getName());
            }

            // 设置java类型
            if (StringUtils.startsWithIgnoreCase(column.getJdbcType(), "CHAR")
                    || StringUtils.startsWithIgnoreCase(column.getJdbcType(), "VARCHAR")
                    || StringUtils.startsWithIgnoreCase(column.getJdbcType(), "TEXT")
                    || StringUtils.startsWithIgnoreCase(column.getJdbcType(), "LONGTEXT")
                    || StringUtils.startsWithIgnoreCase(column.getJdbcType(), "NARCHAR")) {
                column.setJavaType("String");
            } else if (StringUtils.startsWithIgnoreCase(column.getJdbcType(), "DATETIME")
                    || StringUtils.startsWithIgnoreCase(column.getJdbcType(), "DATE")
                    || StringUtils.startsWithIgnoreCase(column.getJdbcType(), "TIMESTAMP")) {
                column.setJavaType("java.util.Date");
                column.setShowType("dateselect");
            } else if (StringUtils.startsWithIgnoreCase(column.getJdbcType(), "BIGINT")
                    || StringUtils.startsWithIgnoreCase(column.getJdbcType(), "INT")
                    || StringUtils.startsWithIgnoreCase(column.getJdbcType(), "NUMBER")) {
                // 如果是浮点型
                String[] ss = StringUtils.split(StringUtils.substringBetween(column.getJdbcType(), "(", ")"), ",");
                if (ss != null && ss.length == 2 && Integer.parseInt(ss[1]) > 0) {
                    column.setJavaType("Double");
                }
                // 如果是整形
                else if (ss != null && ss.length == 1 && Integer.parseInt(ss[0]) <= 10) {
                    column.setJavaType("Integer");
                }
                // 长整形
                else {
                    column.setJavaType("Long");
                }
            } else if (StringUtils.startsWithIgnoreCase(column.getJdbcType(), "BIT")) {
                column.setJavaType("Boolean");
            }

            // 设置java字段名
            column.setJavaField(StringUtils.toCamelCase(column.getName()));

            // 是否是主键
            column.setIsPk(genTable.getPkList().contains(column.getName()) ? "1" : "0");

            // 插入字段
            column.setIsInsert("1");

            // 编辑字段
            if (!StringUtils.equalsIgnoreCase(column.getName(), "id")
                    && !StringUtils.equalsIgnoreCase(column.getName(), "create_by")
                    && !StringUtils.equalsIgnoreCase(column.getName(), "create_date")
                    && !StringUtils.equalsIgnoreCase(column.getName(), "del_flag")) {
                column.setIsEdit("1");
            }

            // 列表字段
            if (StringUtils.equalsIgnoreCase(column.getName(), "name")
                    || StringUtils.equalsIgnoreCase(column.getName(), "title")
                    || StringUtils.equalsIgnoreCase(column.getName(), "remarks")
                    || StringUtils.equalsIgnoreCase(column.getName(), "update_date")) {
                column.setIsList("1");
            }

            // 查询字段
            if (StringUtils.equalsIgnoreCase(column.getName(), "name")
                    || StringUtils.equalsIgnoreCase(column.getName(), "title")) {
                column.setIsQuery("1");
            }

            // 查询字段类型
            if (StringUtils.equalsIgnoreCase(column.getName(), "name")
                    || StringUtils.equalsIgnoreCase(column.getName(), "title")) {
                column.setQueryType("like");
            }

            // 设置特定类型和字段名


            // 创建者、更新者
            else if (StringUtils.startsWithIgnoreCase(column.getName(), "create_by")
                    || StringUtils.startsWithIgnoreCase(column.getName(), "update_by")) {
                column.setJavaField(column.getJavaField() + ".id");

            }
            // 创建时间、更新时间
            else if (StringUtils.startsWithIgnoreCase(column.getName(), "create_date")
                    || StringUtils.startsWithIgnoreCase(column.getName(), "update_date")) {
                column.setShowType("dateselect");
            }
            // 备注、内容
            else if (StringUtils.equalsIgnoreCase(column.getName(), "remarks")
                    || StringUtils.equalsIgnoreCase(column.getName(), "content")) {
                column.setShowType("textarea");
            }
            // 父级ID
            else if (StringUtils.equalsIgnoreCase(column.getName(), "parent_id")) {
                column.setJavaType("This");
                column.setJavaField("parent.id|name");
                column.setShowType("treeselect");
            }
            // 所有父级ID
            else if (StringUtils.equalsIgnoreCase(column.getName(), "parent_ids")) {
                column.setQueryType("like");
            }
            // 删除标记
            else if (StringUtils.equalsIgnoreCase(column.getName(), "del_flag")) {
                column.setShowType("radiobox");
                column.setDictType("del_flag");
            }
        }
    }

    /**
     * 获取模板路径
     *
     * @return
     */
    public static String getTemplatePath() {
        try {
            File file = new DefaultResourceLoader().getResource("").getFile();
            if (file != null) {
                return file.getAbsolutePath() + File.separator + StringUtils.replaceEach(GenCom.class.getName(),
                        new String[]{"util." + GenCom.class.getSimpleName(), "."}, new String[]{"template", File.separator});
            }
        } catch (Exception e) {
            logger.error("{}", e);
        }

        return "";
    }

    public String generateToFile(GenTemplate tpl, Map<String, Object> model, boolean isReplaceFile) throws Exception {
        // 获取生成文件
        String fileName = path + File.separator
                + StringUtils.replaceEach(templateCom.renderString(tpl.getFilePath() + "/", model),
                new String[]{"//", "/", "."}, new String[]{File.separator, File.separator, File.separator})
                + templateCom.renderString(tpl.getFileName(), model);
        logger.debug(" fileName === " + fileName);

        // 获取生成文件内容
        String content = null;
        try {
            content = templateCom.renderString(StringUtils.trimToEmpty(tpl.getContent()), model);
        } catch (Exception e) {
            logger.error("出现异常：" + tpl.getContent(), e);
        }

        logger.debug(" content === \r\n" + content);

        // 如果选择替换文件，则删除原文件
        if (isReplaceFile) {
            FileUtils.deleteFile(fileName);
        }

        // 创建并写入文件
        if (FileUtils.createFile(fileName)) {
            FileUtils.writeStringToFile(new File(fileName), content, Constants.CHARSET.UTF8, true);
            logger.debug(" file create === " + fileName);
            return "生成成功：" + fileName + "<br/>";
        } else {
            logger.debug(" file extents === " + fileName);
            return "文件已存在：" + fileName + "<br/>";
        }
    }

}
